﻿using Composr.Core.Repositories;
using System;
using System.Collections.Generic;

namespace Composr.Core.Services
{
    /// <summary>
    /// facade for CRUD operations
    /// </summary>
    public abstract class Service<T>
    {
        private readonly Repository<T> repository;
        
        public Service(Repository<T> repository)
        {
            if (repository == null)
            {
                throw new ArgumentException("repository cannot be null");
            }
            this.repository = repository;
        }

        public T Get(int id)
        {
            if (Cache.Contains(GetCacheKey(id)))
            {
                return Cache.Get<T>(GetCacheKey(id));
            }

            T t = repository.Get(id);
            if(t != null)
            {
                Cache.Add(GetCacheKey(t), t);
            }
            return t;
        }

        public IEnumerable<T> Get(Filter filter)
        {
            IEnumerable<T> items = repository.Get(filter);
            foreach (var item in items) Cache.Add<T>(GetCacheKey(item), item);
            return items;
        }

        public T Save(T item)
        {
            Validate(item);
            T t1 = repository.Save(item);
            Cache.Add<T>(GetCacheKey(t1), t1);
            return t1;
        }

        public void Delete(T item)
        {
            repository.Delete(item);
            Cache.Remove(GetCacheKey(item));            
        }

        public abstract void Validate(T item);

        public abstract string GetCacheKey(int id);

        public abstract string GetCacheKey(T item);
    }
}
